浅谈秒杀系统
一、业务分析
正常电子商务流程(1)查询商品;(2)创建订单;(3)扣减库存;(4)更新订单;(5)付款;(6)卖家发货
秒杀业务的特性(1)低廉价格;(2)大幅推广;(3)瞬时售空;(4)一般是定时上架;(5)时间短、瞬时并发量高;
二、挑战
1.隔离常规系统:
将秒杀系统独立部署,甚至使用独立域名,使其与网站完全隔离。
2.防止用户频繁刷新:
页面内容静态化。
3.增加网络带宽:
秒杀商品页面缓存cnd,需要同cdn临时租借出口带宽。
4.下单url限制:
url会包含服务端生成的随机数,所以任何人包括研发也无法得到。
5.秒杀按钮控制点亮:
使用JavaScript脚本控制,在秒杀商品静态页面中加入一个JavaScript文件引用,该JavaScript文件中包含 秒杀开始标志为否;当秒杀开始的时候生成一个新的JavaScript文件(文件名保持不变,只是内容不一样),更新秒杀开始标志为是,加入下单页面的URL及随机数参数(这个随机数只会产生一个,即所有人看到的URL都是同一个,服务器端可以用redis这种分布式缓存服务器来保存随机数),并被用户浏览器加载,控制秒杀商品页面的展示。这个JavaScript文件的加载可以加上随机版本号(例如xx.js?v=32353823),这样就不会被浏览器、CDN和反向代理服务器缓存。这个JavaScript文件非常小,即使每次浏览器刷新都访问JavaScript文件服务器也不会对服务器集群和网络带宽造成太大压力。
6.如何只允许第一个提交的订单被发送到订单子系统
7.如何进行下单前置检查
8.秒杀一般是定时上架
9.减库存的操作有两种选择,一种是拍下减库存 另外一种是付款减库存;目前采用的“拍下减库存”的方式,拍下就是一瞬间的事,对用户体验会好些。
10.库存会带来“超卖”的问题
11.秒杀器的应对
A 同步漏斗然后打到redis
首先漏斗 LVS -> nginx 做limit,大量请求返回固定页面 -> WEB(tomcat) 根据网络带宽扩展实例传输页面
-> SOA (tomcat) 根据请求数扩展实例 每个能抗2000
-> redis 用String (DECRBY原子减返回结果)或者 sortedSet(单线程POP) 存 利用单线程原子性操作防止并发
B 请求入队列 同步转异步
超过redis最大承受并发数(极限程度每个商品一片 所以是商品数片数单实例最大tps) 请求放入redis队列(单独的集群)
直接返回排队中(还多少个) 前台timer刷新,直到返回是否秒杀成功
方案A+B 单独有个计数器服务 统计redis当前总连接数,如果超过阈值,所有请求走异步B